using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Security.Cryptography;
using System.Text;

/// <summary>
/// Summary description for EncrypKey
/// </summary>
public class EncrypKey
{
    private const string _EncryptionKey = "ifpftzxbsorj/w/b"; //key used for all connection information

    public enum SymmProvEnum : int
    {
        DES, RC2, Rijndael
    }

    public string EnvryptionKey
    {
        get
        {
            return _EncryptionKey;
        }

    }
    private SymmetricAlgorithm mobjCryptoService;

    /// <remarks>
    /// Constructor for using an intrinsic .Net SymmetricAlgorithm class.
    /// </remarks>
    public EncrypKey(SymmProvEnum NetSelected)
    {
        switch (NetSelected)
        {
            case SymmProvEnum.DES:
                mobjCryptoService = new DESCryptoServiceProvider();
                break;
            case SymmProvEnum.RC2:
                mobjCryptoService = new RC2CryptoServiceProvider();
                break;
            case SymmProvEnum.Rijndael:
                mobjCryptoService = new RijndaelManaged();
                break;
        }
    }

    /// <remarks>
    /// Constructor for using a customized SymmetricAlgorithm class.
    /// </remarks>
    public EncrypKey(SymmetricAlgorithm ServiceProvider)
    {
        mobjCryptoService = ServiceProvider;
    }

    /// <remarks>
    /// Depending on the legal key size limitations of a specific CryptoService provider
    /// and length of the private key provided, padding the secret key with space character
    /// to meet the legal size of the algorithm.
    /// </remarks>
    private byte[] GetLegalKey(string Key)
    {
        string sTemp;
        if (mobjCryptoService.LegalKeySizes.Length > 0)
        {
            int lessSize = 0, moreSize = mobjCryptoService.LegalKeySizes[0].MinSize;
            // key sizes are in bits
            while (Key.Length * 8 > moreSize)
            {
                lessSize = moreSize;
                moreSize += mobjCryptoService.LegalKeySizes[0].SkipSize;
            }
            sTemp = Key.PadRight(moreSize / 8, ' ');
        }
        else
            sTemp = Key;

        // convert the secret key to byte array
        return ASCIIEncoding.ASCII.GetBytes(sTemp);
    }

    public string Encrypting(string Source, string Key)
    {
        String strOutputString;
        String strTmpOutputString;

        String strUpperCaseCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

        byte[] bytIn = System.Text.ASCIIEncoding.ASCII.GetBytes(Source);
        // create a MemoryStream so that the process can be done without I/O files
        System.IO.MemoryStream ms = new System.IO.MemoryStream();

        byte[] bytKey = GetLegalKey(Key);



        // set the private key
        mobjCryptoService.Key = bytKey;
        mobjCryptoService.IV = bytKey;

        // create an Encryptor from the Provider Service instance
        ICryptoTransform encrypto = mobjCryptoService.CreateEncryptor();


        // create Crypto Stream that transforms a stream using the encryption
        CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Write);

        // write out encrypted content into MemoryStream
        cs.Write(bytIn, 0, bytIn.Length);
        cs.FlushFinalBlock();


        // get the output and trim the '\0' bytes
        byte[] bytOut = ms.GetBuffer();
        int i = 0;
        for (i = 0; i < bytOut.Length; i++)
            if (bytOut[i] == 0)
                break;

        // convert into Base64 so that the result can be used in xml
        strTmpOutputString = System.Convert.ToBase64String(bytOut, 0, i);

        strOutputString = "";

        // convert all upper case characters to lower and place add a preceeding "_" to 
        // signal that this character was converted from upper to lower case
        // This conversion is necessary because IIS converts all values to lowercase as it 
        // forwards requests to the portal.  When these values are passed back FROM the portal
        // we have to convert the appropriate characters back to upper case in the decryption 
        // routine

        foreach (char chrElement in strTmpOutputString.ToCharArray())
        {
            if (strUpperCaseCharacters.Contains(chrElement.ToString()))
            {
                strOutputString += "_" + chrElement.ToString().ToLower();
            }
            else
            {
                strOutputString += chrElement.ToString();
            }
        }

        return strOutputString;
    }

    public string Decrypting(string Source, string Key)
    {

        //Convert lower to upper case characters (see encryption for details)
        int nCurIndex = 0;
        byte[] fromEncrypted;
        String strLowerCaseCharacters = "abcdefghijklmnopqrstuvwxyz";
        String strConvertedSource;

        strConvertedSource = "";

        for (int a = 0; a < Source.Length; a++)
        {
            if (Source[a].ToString().CompareTo("_") == 0)
            {

                if (strLowerCaseCharacters.Contains(Source[a + 1].ToString()))
                {
                    strConvertedSource += Source[a + 1].ToString().ToUpper();
                    a += 1;
                }
            }
            else
            {
                strConvertedSource += Source[a].ToString();
            }
        }

        Source = strConvertedSource;

        // convert from Base64 to binary
        byte[] bytIn = System.Convert.FromBase64String(Source);

        // create a MemoryStream with the input
        System.IO.MemoryStream ms = new System.IO.MemoryStream(bytIn, 0, bytIn.Length);

        byte[] bytKey = GetLegalKey(Key);

        // set the private key
        mobjCryptoService.Key = bytKey;
        mobjCryptoService.IV = bytKey;

        // create a Decryptor from the Provider Service instance
        ICryptoTransform encrypto = mobjCryptoService.CreateDecryptor();

        // create Crypto Stream that transforms a stream using the decryption
        CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Read);


        // read out the result from the Crypto Stream
        System.IO.StreamReader sr = new System.IO.StreamReader(cs);

        return sr.ReadToEnd();
    }


}